package com.whsxt.config;

import cn.hutool.core.io.resource.ClassPathResource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;
import org.springframework.security.oauth2.provider.token.store.KeyStoreKeyFactory;

import javax.annotation.Resource;
import java.security.KeyPair;

/*
* 1.token 的存储
* 2.jwt 的转换器
* 3.第三方应用
* 4.endpoints(端口)暴露
* */
@Configuration
public class AuthorizationConfig extends AuthorizationServerConfigurerAdapter {
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Resource
    private AuthenticationManager authenticationManager;
    // @Bean   因为 geo-common 里面已经有这个 Bean 对象了，当我们启动 auth -server 的时候，ego-common 也会被加载
    public TokenStore tokenStore(){
        return new JwtTokenStore(jwtAccessTokenConverter());
    }
    //直接使用非对称加密的方式实现
    // @Bean
    public JwtAccessTokenConverter jwtAccessTokenConverter(){
        JwtAccessTokenConverter jwtAccessTokenConverter=new JwtAccessTokenConverter();
        //把私钥读到内存中去
        ClassPathResource resource=new ClassPathResource("cxs-jwt.jks");
        //创建一个钥匙工厂
        KeyStoreKeyFactory keyStoreKeyFactory = new KeyStoreKeyFactory((org.springframework.core.io.Resource) resource, "shengmengyu520".toCharArray());
        KeyPair privateKey = keyStoreKeyFactory.getKeyPair("cxs-jwt");
        //设置进转换器里面
        jwtAccessTokenConverter.setKeyPair(privateKey);
        //返回一个转换器
        return jwtAccessTokenConverter;
    }
    /*
    * 配置第三方的应用
    * password(密码授权)：只要是登录就用这个授权
    * 客户端授权：用于微服务之间自发的进行远程调用时，资源服务器必须要 token 的情况下；当然也可以放行服务提供者的接口
    * */
    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory()
                .withClient("web")
                //加密
                .secret(passwordEncoder.encode("web-secret"))
                .scopes("all")
                //授权类型：password 授权
                .authorizedGrantTypes("password")
                .accessTokenValiditySeconds(7200)
                .redirectUris("https://www.baidu.com")
                .and()
                .withClient("client")
                .secret(passwordEncoder.encode("client-secret"))
                .scopes("read")
                //客户端授权
                .authorizedGrantTypes("client_credentials")
                .accessTokenValiditySeconds(Integer.MAX_VALUE)  //66年才过期
                .redirectUris("https://www.baidu.com");
    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints.tokenStore(tokenStore())
                .accessTokenConverter(jwtAccessTokenConverter())
                .authenticationManager(authenticationManager);
    }
}
